package org.xiyu.yee.capemanage;

import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.logging.LogUtils;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import org.slf4j.Logger;
import net.minecraft.resources.ResourceLocation;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.locale.Language;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.commands.CommandSourceStack;
import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraft.server.MinecraftServer;

import org.xiyu.yee.capemanage.util.CapeManager;
import org.xiyu.yee.capemanage.data.PlayerCapeData;
import org.xiyu.yee.capemanage.network.CapeUpdatePacket;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

@Mod(Capemanage.MODID)
public class Capemanage {
    public static final String MODID = "capemanage";
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final String[] SPECIAL_PLAYERS = {"God_xiyu","饩雨","fho4565","_fho4565","KGG_xk","KGG_233","KGG_AA","KGG_xt","兰琳亲","Noelle_1337"};
    private static Path gameDir;
    private static File capeFolder;
    private static File eggFolder;
    private static final String PROTOCOL_VERSION = "1";
    public static final SimpleChannel NETWORK_CHANNEL = NetworkRegistry.newSimpleChannel(
        new ResourceLocation(MODID, "main"),
        () -> PROTOCOL_VERSION,
        PROTOCOL_VERSION::equals,
        PROTOCOL_VERSION::equals
    );

    private static final String[] EGG_CAPES = {
            "banana",
            "dragongril",
            "gengsheng",
            "ikun",
            "kobe",
            "fdbclient",
            "kong_xing",
            "cheems",
            "dingzhen",
            "ydmy"
    };

    public Capemanage() {
        IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
        MinecraftForge.EVENT_BUS.register(this);
        
        // 初始化文件夹，使用FMLPaths来获取正确的游戏目录
        gameDir = FMLPaths.GAMEDIR.get();
        capeFolder = gameDir.resolve("cape").toFile();
        eggFolder = gameDir.resolve("cape/egg").toFile();
        
        LOGGER.info("Initializing cape folders at: {}", capeFolder.getAbsolutePath());
        
        if (!capeFolder.exists()) {
            if (capeFolder.mkdirs()) {
                LOGGER.info("Created cape folder");
            } else {
                LOGGER.error("Failed to create cape folder");
            }
        }
        if (!eggFolder.exists()) {
            if (eggFolder.mkdirs()) {
                LOGGER.info("Created egg folder");
            } else {
                LOGGER.error("Failed to create egg folder");
            }
        }
        
        // 注册网络消息
        NETWORK_CHANNEL.registerMessage(0, 
            CapeUpdatePacket.class,
            CapeUpdatePacket::encode,
            CapeUpdatePacket::decode,
            CapeUpdatePacket::handle
        );
    }

    public static File getCapeFolder() {
        return capeFolder;
    }
    
    public static File getEggFolder() {
        return eggFolder;
    }
    
    public static Path getGameDir() {
        return gameDir;
    }

    @SubscribeEvent
    public void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
        if (event.getEntity() instanceof ServerPlayer) {
            ServerPlayer player = (ServerPlayer) event.getEntity();
            String playerName = player.getName().getString();
            File playerDataFile = new File(capeFolder, playerName + ".json");
            
            // 为新玩家分配随机披风
            if (!playerDataFile.exists()) {
                LOGGER.info("First time join detected for player: {}", playerName);
                String randomCape = CapeManager.getRandomCape();
                PlayerCapeData capeData = new PlayerCapeData(playerName, randomCape);
                CapeManager.saveCapeData(playerDataFile, capeData);
                
                // 广播新玩家的披风数据给所有人
                NETWORK_CHANNEL.send(PacketDistributor.ALL.noArg(),
                    new CapeUpdatePacket(playerName, randomCape));
                LOGGER.info("Assigned random cape '{}' to player: {}", randomCape, playerName);
            }
            
            // 同步当前玩家的披风数据给所有人
            PlayerCapeData currentPlayerData = CapeManager.loadCapeData(playerDataFile);
            if (currentPlayerData != null) {
                NETWORK_CHANNEL.send(PacketDistributor.ALL.noArg(),
                    new CapeUpdatePacket(playerName, currentPlayerData.getCapeName()));
            }
            
            // 同步所有在线玩家的披风数据给当前玩家
            MinecraftServer server = player.getServer();
            if (server != null) {
                server.getPlayerList().getPlayers().forEach(otherPlayer -> {
                    if (otherPlayer != player) {
                        String otherPlayerName = otherPlayer.getName().getString();
                        File otherPlayerFile = new File(capeFolder, otherPlayerName + ".json");
                        PlayerCapeData otherCapeData = CapeManager.loadCapeData(otherPlayerFile);
                        if (otherCapeData != null) {
                            // 只发送给当前加入的玩家
                            NETWORK_CHANNEL.send(PacketDistributor.PLAYER.with(() -> player),
                                new CapeUpdatePacket(otherPlayerName, otherCapeData.getCapeName()));
                        }
                    }
                });
            }
        }
    }

    @SubscribeEvent
    public void onRegisterCommands(RegisterCommandsEvent event) {
        event.getDispatcher().register(
            Commands.literal("cape")
                .requires(source -> source.hasPermission(0))
                .executes(context -> {
                    ServerPlayer player = context.getSource().getPlayerOrException();
                    File playerDataFile = new File(capeFolder, player.getName().getString() + ".json");
                    if (playerDataFile.exists()) {
                        PlayerCapeData data = CapeManager.loadCapeData(playerDataFile);
                        if (data != null) {
                            String capeName = data.getCapeName();
                            if (capeName.startsWith("egg.")) {
                                player.sendSystemMessage(Component.translatable("cape.capemanage.command.current", 
                                    Component.literal(capeName)));
                            } else {
                                player.sendSystemMessage(Component.translatable("cape.capemanage.command.current", 
                                    Component.translatable("cape.capemanage." + capeName)));
                            }
                            player.sendSystemMessage(Component.translatable("cape.capemanage.command.status", 
                                Component.literal(data.isCapeEnabled() ? "开启" : "关闭")));
                        }
                    }
                    player.sendSystemMessage(Component.translatable("cape.capemanage.command.usage"));
                    return 1;
                })
                .then(Commands.literal("toggle")
                    .executes(context -> {
                        ServerPlayer player = context.getSource().getPlayerOrException();
                        String playerName = player.getName().getString();
                        File playerDataFile = new File(capeFolder, playerName + ".json");
                        
                        PlayerCapeData capeData;
                        if (playerDataFile.exists()) {
                            capeData = CapeManager.loadCapeData(playerDataFile);
                            if (capeData == null) {
                                capeData = new PlayerCapeData(playerName, CapeManager.getRandomCape());
                            }
                        } else {
                            capeData = new PlayerCapeData(playerName, CapeManager.getRandomCape());
                        }
                        
                        // 切换披风显示状态
                        capeData.setCapeEnabled(!capeData.isCapeEnabled());
                        CapeManager.saveCapeData(playerDataFile, capeData);
                        
                        // 广播更新
                        NETWORK_CHANNEL.send(PacketDistributor.ALL.noArg(), 
                            new CapeUpdatePacket(playerName, capeData.getCapeName()));
                            
                        player.sendSystemMessage(Component.translatable("cape.capemanage.command.toggle." + 
                            (capeData.isCapeEnabled() ? "enabled" : "disabled")));
                        return 1;
                    }))
                .then(Commands.argument("capeName", StringArgumentType.string())
                    .suggests((context, builder) -> suggestCapes(context, builder))
                    .executes(context -> {
                        String capeName = StringArgumentType.getString(context, "capeName");
                        ServerPlayer player = context.getSource().getPlayerOrException();
                        String playerName = player.getName().getString();
                        
                        boolean isSpecialPlayer = Arrays.asList(SPECIAL_PLAYERS).contains(playerName);
                        
                        if (capeName.startsWith("egg.")) {
                            if (!isSpecialPlayer) {
                                player.sendSystemMessage(Component.translatable("cape.capemanage.command.nopermission"));
                                return 0;
                            }
                        }
                        
                        if (!CapeManager.isCapeValid(capeName)) {
                            player.sendSystemMessage(Component.translatable("cape.capemanage.command.notfound"));
                            return 0;
                        }
                        
                        File playerDataFile = new File(capeFolder, playerName + ".json");
                        PlayerCapeData capeData;
                        
                        // 读取现有的披风数据以保持显示状态
                        if (playerDataFile.exists()) {
                            capeData = CapeManager.loadCapeData(playerDataFile);
                            if (capeData != null) {
                                boolean wasEnabled = capeData.isCapeEnabled();
                                capeData = new PlayerCapeData(playerName, capeName);
                                capeData.setCapeEnabled(wasEnabled);
                            } else {
                                capeData = new PlayerCapeData(playerName, capeName);
                            }
                        } else {
                            capeData = new PlayerCapeData(playerName, capeName);
                        }
                        
                        CapeManager.saveCapeData(playerDataFile, capeData);
                        
                        NETWORK_CHANNEL.send(PacketDistributor.ALL.noArg(), 
                            new CapeUpdatePacket(playerName, capeName));
                            
                        player.sendSystemMessage(Component.translatable("cape.capemanage.command.success"));
                        LOGGER.info("Player {} changed cape to: {}", playerName, capeName);
                        return 1;
                    }))
        );
    }

    private CompletableFuture<Suggestions> suggestCapes(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) {
        String input = builder.getRemaining().toLowerCase();
        ServerPlayer player;
        
        try {
            player = context.getSource().getPlayerOrException();
        } catch (CommandSyntaxException e) {
            return builder.buildFuture();
        }
        
        boolean isSpecialPlayer = Arrays.asList(SPECIAL_PLAYERS).contains(player.getName().getString());
        
        // 获取普通披风建议
        Stream<String> normalCapes = CapeManager.getAvailableCapes().stream()
            .filter(name -> Language.getInstance().has("cape.capemanage." + name))
            .sorted();
            
        // 获取彩蛋披风建议
        Stream<String> eggCapes = Arrays.stream(EGG_CAPES)
            .map(name -> "egg." + name)
            .sorted();
            
        // 根据玩家权限过滤显示的披风
        Stream<String> allCapes;
        if (isSpecialPlayer) {
            // 特权玩家可以看到所有披风
            allCapes = Stream.concat(normalCapes, eggCapes);
        } else {
            // 普通玩家只能看到普通披风
            allCapes = normalCapes;
        }
            
        allCapes.filter(name -> name.toLowerCase().startsWith(input))
            .forEach(name -> {
                if (name.startsWith("egg.")) {
                    builder.suggest(name, Component.literal("特殊披风: " + name.substring(4)));
                } else {
                    MutableComponent displayName = Component.translatable("cape.capemanage." + name);
                    builder.suggest(name, displayName);
                }
            });
            
        return builder.buildFuture();
    }
}
